﻿#pragma once
namespace LK
{
	namespace Reflection
	{
		struct PLibraryNode:PObject
		{
			PMETHODS(PLibraryNode,LibraryNode);
			//构造函数
			PLibraryNode(WeakPtr<PTypeLibrary> const& library, PDomainNode const&baseNode = PLibraryNode::EmptyNode, PString const& name = PString::GetEmpty());
			//获取名称
			PString GetName()const;
			//获取全路径名称
			PString GetFullName()const;
			//获取基节点
			PDomainNode GetBaseNode()const;
			//设置名称
			void SetName(PString const&)const;
			//设置基节点
			void SetBaseNode(PDomainNode const&)const;
			//获取基库
			WeakPtr<PTypeLibrary> GetLibrary()const;
			//设置基库
			void SetLibrary(WeakPtr<PTypeLibrary> const&)const;
			//清理
			void Clear()const;
			/**
			@brief 比较两个节点的大小*/
			static index_t Compare(PLibraryNode const&, PLibraryNode const&);
			/**
			@brief 比较节点与字符串的大小*/
			static index_t StringCompare(PLibraryNode const&, PString const&);
			//空节点
			static const PDomainNode EmptyNode;
		};
		struct LibraryNode:Object
		{
			BMETHODS(PLibraryNode, LibraryNode)
			//重写Object::ToString方法
			PString ToString()const;
			//构造函数，构造时必须传入基库弱引用
			LibraryNode(WeakPtr<PTypeLibrary> const& library, PDomainNode const&baseNode= PLibraryNode::EmptyNode,PString const& name=PString::GetEmpty());
			//获取基库
			WeakPtr<PTypeLibrary> GetLibrary()const;
			//获取名称
			PString GetName()const;
			//获取基节点
			PDomainNode GetBaseNode()const;
			//设置基库
			virtual void SetLibrary(PTypeLibrary const&);
			//清理，清除所有引用和下属所有信息
			virtual void Clear();
			//设置名称
			void SetName(PString const&);
			//设置基节点
			void SetBaseNode(PDomainNode const&);
		private:
			//名称
			PString Name;
			//基节点
			PLibraryNode BaseNode;
			//基库
			WeakPtr<PObject> Library;
		};

		struct PDomainNode :PLibraryNode
		{
			PMETHODS(PDomainNode, DomainNode);
			/**
			@brief 获取内部节点数组的引用*/
			Collection::PArray<PLibraryNode>& GetInnerNodesRef()const;
			/**
			@brief 添加一个内部节点，并返回该节点，按节点名称进行排序。
			@note 如果已存在该名称节点，则直接返回内部保存的同名节点*/
			PLibraryNode AddInnerNode(PLibraryNode node)const;
			/**
			@brief 获取当前节点下一个名为str的子节点，如果没有指定名称的子节点，则返回NULL*/
			PLibraryNode GetInnerNodeByName(PString const & str)const;
			/**
			@brief 移除指定的内部节点*/
			void RemoveInnerNode(PLibraryNode const&node)const;
			/**
			@brief 构造一个域节点*/
			PDomainNode(WeakPtr<PTypeLibrary> const& library, PDomainNode const&baseNode = PLibraryNode::EmptyNode, PString const& name = PString::GetEmpty());
		};
		struct DomainNode :LibraryNode
		{
			BMETHODS(PDomainNode, DomainNode)
			/**
			@brief 内部节点数组*/
			Collection::PArray<PLibraryNode> InnerNodes;
			/**
			@brief 构造一个域节点*/
			DomainNode(WeakPtr<PTypeLibrary> const& library, PDomainNode const&baseNode = PLibraryNode::EmptyNode, PString const& name = PString::GetEmpty());
			/**
			@brief 清理内部数据*/
			void Clear();
			/**
			@brief 添加一个内部节点，并返回该节点，按节点名称进行排序。
			@note 如果已存在该名称节点，则直接返回内部保存的同名节点*/
			PLibraryNode AddInnerNode(PLibraryNode node);
			/**
			@brief 获取当前节点下一个名为str的子节点，如果没有指定名称的子节点，则返回NULL*/
			PLibraryNode GetInnerNodeByName(PString const & str)const;
		};
	}
}
